#include<iostream>
#include"Date.hpp"
using namespace std;
Date::Date(){
	this->m_year=0;
	this->m_month=0;
	this->m_day=0;
	this->m_hour=0;
	this->m_minute=0;
}
Date::Date(int t_year, int t_month, int t_day, int t_hour, int t_minute){
	this->m_year=t_year;
	this->m_month=t_month;
	this->m_day=t_day;
	this->m_hour=t_hour;
	this->m_minute=t_minute;
}
Date::Date(const std::string &dateString){
	int year=0;
	int month=0;
	int day=0;
	int hour=0;
	int minute=0;
	bool v=true;
	if(dateString.size()!=16){
		this->m_year=0;
		this->m_month=0;
		this->m_day=0;
		this->m_hour=0;
		this->m_minute=0;
		v=false;
	}
	if(dateString[4]!='-'||dateString[7]!='-'||dateString[10]!='/'||dateString[13]!=':'){
		this->m_year=0;
		this->m_month=0;
		this->m_day=0;
		this->m_hour=0;
		this->m_minute=0;
		v=false;
	}
	for(int i=0;i<16;i++){
  		if(i==4||i==7||i==10||i==13){
  			
		}	
		else{
			if(dateString[i]<'0'||dateString[i]>'9'){
				this->m_year=0;
				this->m_month=0;
				this->m_day=0;
				this->m_hour=0;
				this->m_minute=0;
				v=false;
			}
		}
	}
	if(v){
		for(int i=0;i<4;i++){
			year=year*10+dateString[i]-'0';
		}
		for(int i=5;i<=6;i++){
			month=month*10+dateString[i]-'0';
		}
		for(int i=8;i<=9;i++){
			day=day*10+dateString[i]-'0';
		}
		for(int i=11;i<=12;i++){
			hour=hour*10+dateString[i]-'0';
		}
		for(int i=14;i<=15;i++){
			minute=minute*10+dateString[i]-'0';
		}
		this->m_year=year;
		this->m_month=month;
		this->m_day=day;
		this->m_hour=hour;
		this->m_minute=minute;
	}
}
int Date::getYear(void) const{
	return this->m_year;
}
void Date::setYear(const int t_year){
	this->m_year=t_year;
}
int Date::getMonth(void) const{
	return this->m_month;
}
void Date::setMonth(const int t_month){
	this->m_month=t_month;
}
int Date::getDay(void) const{
	return this->m_day;
}
void Date::setDay(const int t_day){
	this->m_day=t_day;
}
int Date::getHour(void) const{
	return this->m_hour;
}
void Date::setHour(const int t_hour){
	this->m_hour=t_hour;
}
int Date::getMinute(void) const{
	return this->m_minute;
}
void Date::setMinute(const int t_minute){
	this->m_minute=t_minute;
}
bool Date::isValid(const Date &t_date){
	if(t_date.getYear()<1000||t_date.getYear()>9999){
		return false;
	}
	if(t_date.getMonth()<1||t_date.getMonth()>12){
		return false;
	}
	if(t_date.getMonth()==1||t_date.getMonth()==3||t_date.getMonth()==5||t_date.getMonth()==7||t_date.getMonth()==8||t_date.getMonth()==10||t_date.getMonth()==12){
		if(t_date.getDay()<1||t_date.getDay()>31){
			return false;
		}
	}
	if(t_date.getMonth()==4||t_date.getMonth()==6||t_date.getMonth()==9||t_date.getMonth()==11){
		if(t_date.getDay()<1||t_date.getDay()>30){
			return false;
		}
	}
	if(t_date.getMonth()==2){
		if(t_date.getYear()%400==0||(t_date.getYear()%4==0&&t_date.getYear()%100!=0)){
			if(t_date.getDay()<1||t_date.getDay()>29){
				return false;
			}
		}
		else{
			if(t_date.getDay()<1||t_date.getDay()>28){
				return false;
			}
		}
	}
	if(t_date.getHour()<0||t_date.getHour()>23){
		return false;
	}
	if(t_date.getMinute()<0||t_date.getMinute()>59){
		return false;
	}
	return true;
}
 Date Date::stringToDate(const std::string &t_dateString){
	Date d=Date(0,0,0,0,0);
	int year=0;
	int month=0;
	int day=0;
	int hour=0;
	int minute=0;
	if(t_dateString.size()!=16){
		return d;
	}
	if(t_dateString[4]!='-'||t_dateString[7]!='-'||t_dateString[10]!='/'||t_dateString[13]!=':'){
		return d;
	}
	for(int i=0;i<16;i++){
		if(i==4||i==7||i==10||i==13){
			
		}
		else{
			if(t_dateString[i]<'0'||t_dateString[i]>'9'){
				return d;
			}
		}
	}
	Date d1(t_dateString);
	return d1;
}
string Date::dateToString(const Date& t_date){ 
	if(t_date.isValid(t_date) ==false){
    	string str1 = "0000-00-00/00:00";
    	return str1;
  	}
  	int year;
  	int month;
  	int day;
  	int hour;
  	int minute;
  	year=t_date.m_year;
  	month=t_date.m_month;
  	day=t_date.m_day;
  	hour=t_date.m_hour;
  	minute=t_date.m_minute;
  	string str;
  	str.push_back(year/1000+'0');
  	int three=year-(year/1000)*1000;
  	str.push_back(three/100+'0');
  	int two=three-(three/100)*100;
  	str.push_back(two/10+'0');
  	str.push_back(two%10+'0');
  	str.push_back('-');
  	str.push_back(month/10+'0');
  	str.push_back(month%10+'0');
  	str.push_back('-');
  	str.push_back(day/10+'0');
  	str.push_back(day%10+'0');
  	str.push_back('/');
  	str.push_back(hour/10+'0');
  	str.push_back(hour%10+'0');
  	str.push_back(':');
  	str.push_back(minute/10+'0');
 	str.push_back(minute%10+'0');
  	return str;
}
Date & Date::operator=(const Date &t_date){
	this->m_year=t_date.m_year;
	this->m_month=t_date.m_month;
	this->m_day=t_date.m_day;
	this->m_hour=t_date.m_hour;
	this->m_minute=t_date.m_minute;
	return (*this);
}
bool Date::operator==(const Date &t_date) const{
	if(this->m_year==t_date.m_year&&this->m_month==t_date.m_month&&this->m_day==t_date.m_day&&this->m_hour==t_date.m_hour&&this->m_minute==t_date.m_minute){
		return true;
	}
	else{
		return false;
	}
}
bool Date::operator>(const Date &t_date) const{
	if(this->m_year>t_date.m_year){
		return true;
	}
	else if(this->m_year<t_date.m_year){
		return false;
	}
	else{
		if(this->m_month>t_date.m_month){
			return true;
		}
		else if(this->m_month<t_date.m_month){
			return false;
		}
		else{
			if(this->m_day>t_date.m_day){
				return true;
			}
			else if(this->m_day<t_date.m_day){
				return false;
			}
			else{
				if(this->m_hour>t_date.m_hour){
					return true;
				}
				else if(this->m_hour<t_date.m_hour){
					return false;
				}
				else{
					if(this->m_minute>t_date.m_minute){
						return true;
					}
					else if(this->m_minute<=t_date.m_minute){
						return false;
					}
				}
			}
		}
	}
}
bool Date::operator<(const Date &t_date) const{
		if(this->m_year<t_date.m_year){
		return true;
	}
	else if(this->m_year>t_date.m_year){
		return false;
	}
	else{
		if(this->m_month<t_date.m_month){
			return true;
		}
		else if(this->m_month>t_date.m_month){
			return false;
		}
		else{
			if(this->m_day<t_date.m_day){
				return true;
			}
			else if(this->m_day>t_date.m_day){
				return false;
			}
			else{
				if(this->m_hour<t_date.m_hour){
					return true;
				}
				else if(this->m_hour>t_date.m_hour){
					return false;
				}
				else{
					if(this->m_minute<t_date.m_minute){
						return true;
					}
					else if(this->m_minute>=t_date.m_minute){
						return false;
					}
				}
			}
		}
	}
}
 
bool Date::operator>=(const Date &t_date) const{
	if((*this)>t_date||(*this)==t_date){
		return true;
	}
	else{
		return false;
	}
}
bool Date::operator<=(const Date &t_date) const{
	if((*this)<t_date||(*this)==t_date){
		return true;
	}
	else{
		return false;
	}
}